package com.smasher.core.encrypt.symmetric;


import android.util.Base64;

import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;


/**
 * AES 工具类
 */
public class AESUtil {

    public static final String TAG = "AESUtil";


    private static final String ALGORITHM = "AES";
    private static final String CIPHER_TRANSFORMATION = "AES/CBC/PKCS5Padding";


    /**
     * 生成 AES 密钥。
     *
     * @return Base64 编码的密钥字符串
     */
    public static String generateKey(AESKeySize keySize) {
        try {
            KeyGenerator keyGen = KeyGenerator.getInstance(ALGORITHM);
            keyGen.init(keySize.getSize());
            SecretKey secretKey = keyGen.generateKey();
            return Base64.encodeToString(secretKey.getEncoded(), Base64.NO_WRAP);
        } catch (Exception e) {
            throw new RuntimeException("Failed to generate AES key", e);
        }
    }

    /**
     * 生成随机的初始化向量 (IV)。
     *
     * @return Base64 编码的 IV 字符串
     */
    public static String generateIv() {
        //AES 密钥长度和 IV 长度
        //AES-128：使用 128 位（16 字节）密钥，IV 长度为 128 位（16 字节）。
        //AES-192：使用 192 位（24 字节）密钥，IV 长度仍为 128 位（16 字节）。
        //AES-256：使用 256 位（32 字节）密钥，IV 长度仍为 128 位（16 字节）。
        byte[] iv = new byte[16]; // AES-128 需要 16 字节 IV
        new SecureRandom().nextBytes(iv);
        return Base64.encodeToString(iv, Base64.NO_WRAP);
    }

    /**
     * 使用给定的密钥和 IV 对数据进行 AES 加密。
     *
     * @param data 数据字符串
     * @param key  Base64 编码的密钥字符串
     * @param iv   Base64 编码的 IV 字符串
     * @return Base64 编码的加密数据字符串
     */
    public static String encrypt(String data, String key, String iv) {
        try {
            Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMATION);
            SecretKeySpec keySpec = new SecretKeySpec(Base64.decode(key, Base64.NO_WRAP), ALGORITHM);
            IvParameterSpec ivSpec = new IvParameterSpec(Base64.decode(iv, Base64.NO_WRAP));
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);

            byte[] encryptedData = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
            return Base64.encodeToString(encryptedData, Base64.NO_WRAP);
        } catch (Exception e) {
            throw new RuntimeException("Encryption failed", e);
        }
    }

    /**
     * 使用给定的密钥和 IV 对数据进行 AES 解密。
     *
     * @param encryptedData Base64 编码的加密数据字符串
     * @param key           Base64 编码的密钥字符串
     * @param iv            Base64 编码的 IV 字符串
     * @return 解密后的数据字符串
     */
    public static String decrypt(String encryptedData, String key, String iv) {
        try {
            Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMATION);
            SecretKeySpec keySpec = new SecretKeySpec(Base64.decode(key, Base64.NO_WRAP), ALGORITHM);
            IvParameterSpec ivSpec = new IvParameterSpec(Base64.decode(iv, Base64.NO_WRAP));
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);

            byte[] decodedData = Base64.decode(encryptedData, Base64.NO_WRAP);
            byte[] decryptedData = cipher.doFinal(decodedData);
            return new String(decryptedData);
        } catch (Exception e) {
            throw new RuntimeException("Decryption failed", e);
        }
    }
}
